<template>
	<view class="pricke">
		<uni-transition v-if="mark" ref="aniMark" custom-class="transition" mode-class="fade" :styles="stylesMark"
			:show="show" @click="clickMark"></uni-transition>
		<uni-transition ref="ani" custom-class="transition" :mode-class="modeClass" :styles="styles" :show="show">
			<view class="m-picker">
				<view class="m-picker__case" :style="{
					background: bgColor,
					borderTopLeftRadius: radius[0] + 'rpx',
					borderTopRightRadius: radius[1] + 'rpx',
					borderBottomLeftRadius: radius[2] + 'rpx',
					borderBottomRightRadius: radius[3] + 'rpx',
					paddingBottom: model == 'bottom' ? 'calc(constant(safe-area-inset-bottom) + 30rpx)' : '30rpx',
					paddingBottom: model == 'bottom' ? 'calc(env(safe-area-inset-bottom) + 30rpx)' : '30rpx'
				}">
					<slot v-if="model == 'bottom'" name="handle">
						<view class="handle">
							<view class="button cancel" :style="cancelStyle" @click="cancel">{{cancelText}}</view>
							<view class="button confirm" :style="confirmStyle" @click="confirm">{{confirmText}}</view>
						</view>
					</slot>
					<slot>
						<view class="content" :style="{height: `${height}rpx`}">
							<picker-view class="picker-view" :indicator-class="indicatorClass"
								:indicator-style="indicatorStyle" :value="pickerValue" @change="bindChange"
								@pickstart="pickstart" @pickend="pickend">
								<picker-view-column v-for="(rangeItem, rangeIndex) in range" :key="rangeIndex">
									<view class="picker-view__item" v-for="(item, index) in rangeItem" :key="index">
										{{ item[rangeKey] }}
									</view>
								</picker-view-column>
							</picker-view>
						</view>
					</slot>
					<slot v-if="model != 'bottom'" name="handle">
						<view class="handle">
							<view class="button cancel" :style="cancelStyle" @click="cancel">{{cancelText}}</view>
							<view class="button confirm" :style="confirmStyle" @click="confirm">{{confirmText}}</view>
						</view>
					</slot>
				</view>
			</view>
		</uni-transition>
	</view>
</template>

<script>
	/**
	 * PickerPopup 弹窗滚动选择器
	 * @property {Boolean} mark = [true|false] 是否显示遮罩
	 * @property {Boolean} markClose = [true|false] 点击遮罩是否关闭
	 * @property {Boolean} btnClose = [true|false] 点击按钮是否关闭
	 * @property {Boolean} show = [true|false] 是否显示弹窗
	 * @property {Array} range 数据
	 * @property {String} rangeKey picker-item显示内容的key, 默认 label
	 * @property {String} indicatorStyle 设置选择器中间选中框的样式
	 * @property {String} indicatorClass 设置选择器中间选中框的类名，注意页面或组件的style中写了scoped时，需要在类名前写/deep/
	 * @property {String} cancelText cancel文字
	 * @property {String} confirmText confirm文字
	 * @property {Object} cancelStyle cancel样式style
	 * @property {Object} confirmStyle cancel样式style
	 * @property {Number} height 内容高度 rpx
	 * @property {Number} borderRadius 圆角 rpx
	 * @property {String} bgColor 背景颜色
	 * @property {String} markBgColor mark 背景颜色
	 * @property {String} mode 方向 top/bottom/center
	 * 
	 * @event {Function} cancel 点击取消按钮
	 * @event {Function} confirm 点击确认按钮
	 */
	export default {
		name: "JarvisPicker",
		props: {
			// 是否显示遮罩
			mark: {
				type: Boolean,
				default: true
			},
			// 点击遮罩是否关闭
			markClose: {
				type: Boolean,
				default: true
			},
			// 点击按钮是否关闭
			btnClose: {
				type: Boolean,
				default: true
			},
			// 是否显示弹窗
			show: {
				type: Boolean,
				default: false
			},
			// 数据
			range: {
				type: Array,
				default: () => ([])
			},
			// picker-item显示内容的key
			rangeKey: {
				type: String,
				default: 'label'
			},
			// 设置选择器中间选中框的样式
			indicatorStyle: {
				type: String,
				default: 'height: 50px;'
			},
			// 设置选择器中间选中框的类名，注意页面或组件的style中写了scoped时，需要在类名前写/deep/
			indicatorClass: {
				type: String,
				default: ''
			},
			// cancel文字
			cancelText: {
				type: String,
				default: '取消'
			},
			// confirm文字
			confirmText: {
				type: String,
				default: '确定'
			},
			// cancel样式style
			cancelStyle: {
				type: Object,
				default: () => ({})
			},
			// confirm样式style
			confirmStyle: {
				type: Object,
				default: () => ({})
			},
			// 内容高度 rpx
			height: {
				type: Number,
				default: 500
			},
			// 圆角 rpx
			borderRadius: {
				type: Number,
				default: 16
			},
			// 背景颜色
			bgColor: {
				type: String,
				default: '#FFFFFF'
			},
			// mark 背景颜色
			markBgColor: {
				type: String,
				default: '#00000080'
			},
			// 方向 top/bottom/center
			mode: {
				type: String,
				default: 'bottom'
			}
		},
		data() {
			return {
				pickerValue: [], // 选中的索引
				isScoll: false, // 是否正在滚动
			};
		},
		computed: {
			model() {
				if (this.mode == 'top') return 'top';
				else if (this.mode == 'bottom') return 'bottom';
				else if (this.mode == 'center') return 'center';
				else return 'bottom';
			},
			stylesMark() {
				return {
					position: 'fixed',
					top: 0,
					left: 0,
					right: 0,
					bottom: 0,
					zIndex: 99,
					backgroundColor: this.markBgColor,
				}
			},
			styles() {
				const top = {
					position: 'fixed',
					left: 0,
					right: 0,
					top: 0,
					zIndex: 100
				}
				const bottom = {
					position: 'fixed',
					left: 0,
					right: 0,
					bottom: 0,
					zIndex: 100
				}
				const center = {
					position: 'fixed',
					left: '50%',
					top: '50%',
					width: '90vw',
					transform: 'translate(-50%, -50%)',
					zIndex: 100
				}
				if (this.model == 'top') return top;
				else if (this.model == 'bottom') return bottom;
				else if (this.model == 'center') return center;
				else return bottom;
			},
			radius() {
				const borderRadius = this.borderRadius;
				if (this.model == 'top') return [0, 0, borderRadius, borderRadius];
				else if (this.model == 'bottom') return [borderRadius, borderRadius, 0, 0];
				else if (this.model == 'center') return [borderRadius, borderRadius, borderRadius, borderRadius];
				else return [0, 0, 0, 0];
			},
			modeClass() {
				if (this.model == 'top') return ['fade', 'slide-top'];
				else if (this.model == 'bottom') return ['fade', 'slide-bottom'];
				else if (this.model == 'center') return 'fade';
				else return ['fade', 'slide-bottom'];
			}
		},
		watch: {
			range(val) {
				if (val.length) {
					let arr = []
					for (let index in this.range) {
						arr.push(0);
					}
					this.pickerValue = arr;
				}
			}
		},
		created() {
			if (this.range && this.range.length) {
				this.pickerValue = [];
				for (let index in this.range) {
					this.pickerValue.push(0)
				}
			}
		},
		methods: {
			/**
			 * 关闭
			 */
			close() {
				if (!this.isScoll) this.$emit('update:show', false)
			},
			/**
			 * 取消
			 */
			cancel() {
				this.$emit('cancel')
				if (this.btnClose) this.close()
			},
			/**
			 * 确定
			 */
			confirm() {
				// 滚动结束后才能点击
				if (!this.isScoll) {
					this.$emit('confirm', this.pickerValue);
					if (this.btnClose) this.close()
				}
			},
			/**
			 * 点击遮罩
			 */
			clickMark() {
				if (this.markClose) this.close()
			},
			/**
			 * picker-view 改变
			 * @param {Object} e
			 */
			bindChange(e) {
				const val = e.detail.value;
				this.pickerValue = val;
			},
			/**
			 * picker-view开始滚动
			 */
			pickstart() {
				this.isScoll = true;
			},
			/**
			 * picker-view 滚动结束
			 */
			pickend() {
				this.isScoll = false;
			}
		}
	}
</script>

<style lang="scss">
	.m-picker {
		width: 100%;
		height: 100%;

		&__case {
			padding-left: 56rpx;
			padding-right: 56rpx;
			padding-top: 30rpx;
			padding-bottom: 30rpx;

			.handle {
				width: 100%;
				display: flex;
				align-items: center;
				justify-content: space-between;

				.button {
					font-size: 28rpx;
					font-family: PingFang SC;
					font-weight: 500;
					color: #000000;

					&.cancel {}

					&.confirm {
						color: #FF8833;
					}
				}
			}

			.content {
				width: 100%;
				height: 400rpx;
			}

		}
	}

	.picker-view {
		width: 100%;
		height: 100%;

		&__item {
			display: flex;
			align-items: center;
			justify-content: center;
			font-size: 28rpx;
		}
	}
</style>